﻿namespace Microsoft.SharePoint.Client
{
    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;

    internal sealed class ClientQueryProvider : IQueryProvider
    {
        IQueryable<TElement> IQueryProvider.CreateQuery<TElement>(Expression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            if (!typeof(IQueryable<TElement>).IsAssignableFrom(expression.Type))
            {
                throw new ArgumentOutOfRangeException("expression");
            }
            return new ClientQueryable<TElement>(this, expression);
        }

        IQueryable IQueryProvider.CreateQuery(Expression expression)
        {
            IQueryable queryable;
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }
            Type elementType = ExpressionUtility.GetElementType(expression.Type);
            if (elementType == null)
            {
                return null;
            }
            try
            {
                queryable = (IQueryable) Activator.CreateInstance(typeof(ClientQueryable<>).MakeGenericType(new Type[] { elementType }), new object[] { this, expression });
            }
            catch (TargetInvocationException exception)
            {
                throw exception.InnerException;
            }
            return queryable;
        }

        TResult IQueryProvider.Execute<TResult>(Expression expression)
        {
            throw new NotSupportedException(Resources.GetString("InvalidQueryExecution"));
        }

        object IQueryProvider.Execute(Expression expression)
        {
            throw new NotSupportedException(Resources.GetString("InvalidQueryExecution"));
        }
    }
}

